package com.example.flowabledemo.controller;

import cn.hutool.core.util.StrUtil;
import com.example.flowabledemo.common.HttpCode;
import com.example.flowabledemo.common.flowable.ProcessValues;
import com.example.flowabledemo.data.dto.ResponsePageResult;
import com.example.flowabledemo.data.dto.ResponseResult;
import com.example.flowabledemo.data.pojo.SecUser;
import com.example.flowabledemo.data.vo.ApplyLeaveVo;
import com.example.flowabledemo.service.FlowableService;
import com.example.flowabledemo.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * @author linke
 * @date 2020/11/26 23:13
 * @description
 */
@Controller
@RequestMapping("user")
@Api(value = "用户相关操作", tags = "UserController")
public class UserController {

  @Autowired
  private HttpServletRequest request;
  @Autowired
  private HttpServletResponse response;
  @Autowired
  private UserService userService;
  @Autowired
  private FlowableService flowableService;

  @GetMapping("me")
  public String me() {
    return "user/me";
  }

  @PreAuthorize("hasAnyRole('USER')")//需要用户角色
  @GetMapping("applyLeave")
  public String applyLeave() {
    SecUser user = userService.getUser();
    int count = flowableService.getRunProcessNumber(user.getUsername(), ProcessValues.TYPE_LEAVE);
    if (count > 0) {
      request.setAttribute("message", "已经存在请假流程，无法再发起申请。请处理完已存在的流程！");
      return "status/message";
    }
    return "process/apply_leave";
  }

  @ApiOperation(value = "用户-发起请假申请", notes = "发起请假申请，status=1表示发起、status=0表示暂存")
  @PostMapping("applyLeave")
  @ResponseBody
  public ResponseResult applyLeavePost(@Valid ApplyLeaveVo applyLeaveVo, String status) {
    if (StrUtil.isBlank(status)) {
      return new ResponseResult(HttpCode.VALIDATION, "入参status不能为空！");
    }
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    Date start = null, end = null;
    try {
      start = sdf.parse(applyLeaveVo.getStartDate());
    } catch (ParseException e) {
      return new ResponseResult(HttpCode.VALIDATION, "入参开始时间错误");
    }
    try {
      end = sdf.parse(applyLeaveVo.getStartDate());
    } catch (ParseException e) {
      return new ResponseResult(HttpCode.VALIDATION, "入参结束时间错误");
    }
    if (start.getTime() > end.getTime()) {
      return new ResponseResult(HttpCode.VALIDATION, "开始时间不能大于结束时间！");
    }
    return userService.applyLeave(applyLeaveVo, status);
  }

  @ApiOperation(value = "用户-编辑请假申请", notes = "编辑请假申请")
  @PostMapping("editLeave/{processId}")
  @ResponseBody
  public ResponseResult editLeavePost(@PathVariable("processId") String processId, String status, @Valid ApplyLeaveVo applyLeaveVo,
      String processRemarks) {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    Date start = null, end = null;
    try {
      start = sdf.parse(applyLeaveVo.getStartDate());
    } catch (ParseException e) {
      return new ResponseResult(HttpCode.VALIDATION, "入参开始时间错误");
    }
    try {
      end = sdf.parse(applyLeaveVo.getStartDate());
    } catch (ParseException e) {
      return new ResponseResult(HttpCode.VALIDATION, "入参结束时间错误");
    }
    if (start.getTime() > end.getTime()) {
      return new ResponseResult(HttpCode.VALIDATION, "开始时间不能大于结束时间！");
    }
    if (StrUtil.isBlank(processId)) {
      return new ResponseResult(HttpCode.VALIDATION, "入参editLeave/{processId}不能为空");
    }
    if (StrUtil.isBlank(status)) {
      return new ResponseResult(HttpCode.VALIDATION, "入参status不能为空");
    }
    if (!ProcessValues.STATUS_SAVE.equals(status) && !ProcessValues.STATUS_SUBMIT.equals(status)
        && !ProcessValues.STATUS_UPDATE.equals(status)) {
      return new ResponseResult(HttpCode.VALIDATION, "入参status错误：0/1/2");
    }
    return userService.editLeave(processId, status, applyLeaveVo, processRemarks);
  }

  @GetMapping("getProcess")
  @ResponseBody
  public ResponsePageResult getProcess(String status, Integer page, Integer limit) {
    if (page == null || limit == null) {
      return new ResponsePageResult(HttpCode.VALIDATION, "入参page、limit不能为空");
    }
    if (page < 0 || page > 999) {
      return new ResponsePageResult(HttpCode.VALIDATION, "入参page范围：1~999");
    }
    if (limit < 0 || limit > 100) {
      return new ResponsePageResult(HttpCode.VALIDATION, "入参limit范围：1~100");
    }
    return flowableService.getProcess(status, page, limit);
  }

  @GetMapping("editLeave/{processId}")
  public String editLeave(@PathVariable("processId") String processId, String status) {
    if (StrUtil.isBlank(status)) {
      throw new RuntimeException("入参status错误：0/1/2");
    }
    if (!ProcessValues.STATUS_SUBMIT.equals(status) && !ProcessValues.STATUS_SAVE.equals(status)
        && !ProcessValues.STATUS_UPDATE.equals(status)) {
      throw new RuntimeException("入参status错误：0/1/2");
    }
    request.setAttribute("vo", flowableService.getApplyLeaveVo(processId));
    request.setAttribute("processId", processId);
    request.setAttribute("status", status);
    return "process/edit_leave";
  }

  @PreAuthorize("hasRole('USER')")
  @ApiOperation(value = "撤销流程", notes = "需要用户角色才能撤销该流程")
  @PostMapping("cancelProcess/{processId}")
  @ResponseBody
  public ResponseResult cancelProcess(@PathVariable("processId") String processId, String reason) {
    if (StrUtil.isBlank(processId)) {
      return new ResponseResult(HttpCode.VALIDATION, "入参editLeave/{processId}不能为空");
    }
    if (StrUtil.isBlank(reason)) {
      return new ResponseResult(HttpCode.VALIDATION, "入参撤销说明reason不能为空");
    }
    return flowableService.cancelProcess(userService.getUser().getUsername(), processId, reason);
  }
}
